from tests.pytests.helpers.codegen_helpers import compile_chunk, assert_code_contains


def test_named_logging_keyword_args():
    """测试命名参数和位置参数的日志写法"""
    src = """
from mc.log import ilog, dlog, wlog

def f(x: int) -> None:
    ilog("val={x}", x=x)
    dlog("val={x} {y}", x=x, y=y)
    wlog("val={} {}", x, y)
"""
    block = compile_chunk(src)
    assert_code_contains(
        block,
        """
        void f(int x) {
            ilog("val={x}", ("x", x));
            dlog("val={x} {y}", ("x", x), ("y", y));
            wlog("val={} {}", x, y);
        }
        """,
    )


def test_position_args_logging():
    """测试位置参数日志 - 自增索引 {}"""
    src = """
from mc.log import ilog

def test_position(name: str, age: int) -> None:
    # 自增索引 {} - 按参数顺序自动填充
    ilog("{} {}", "Hello", "World")
    ilog("User: {} is {} years old", name, age)
"""
    block = compile_chunk(src)
    assert_code_contains(
        block,
        """
        void test_position(const std::string& name, int age) {
            ilog("{} {}", "Hello", "World");
            ilog("User: {} is {} years old", name, age);
        }
        """,
    )


def test_explicit_index_logging():
    """测试显式索引位置参数 - {0}, {1}, {2}"""
    src = """
from mc.log import ilog

def test_explicit() -> None:
    # 显式索引 {0}, {1} - 指定参数索引
    ilog("{1} {0}", "World", "Hello")
    ilog("{0} {1} {0}", "A", "B")
    ilog("{2} {0} {1}", "first", "second", "third")
"""
    block = compile_chunk(src)
    assert_code_contains(
        block,
        """
        void test_explicit() {
            ilog("{1} {0}", "World", "Hello");
            ilog("{0} {1} {0}", "A", "B");
            ilog("{2} {0} {1}", "first", "second", "third");
        }
        """,
    )


def test_mixed_index_types():
    """测试混合索引类型 - 自增索引、显式索引、命名参数"""
    src = """
from mc.log import ilog

def test_mixed_index(user: str, score: int) -> None:
    # 混合自增索引和命名参数
    ilog("{} is {age} years old", "Alice", age=25)
    
    # 混合显式索引和命名参数  
    ilog("{0} has {balance} dollars", "Bob", balance=123.45)
    
    # 混合所有类型（显式索引、自增索引、命名参数）
    ilog("{1} {name} {0}", "Hello", "Test", name="World")
"""
    block = compile_chunk(src)
    assert_code_contains(
        block,
        """
        void test_mixed_index(const std::string& user, int score) {
            ilog("{} is {age} years old", "Alice", ("age", 25));
            ilog("{0} has {balance} dollars", "Bob", ("balance", 123.45));
            ilog("{1} {name} {0}", "Hello", "Test", ("name", "World"));
        }
        """,
    )


def test_named_args_logging():
    """测试命名参数日志 - 命名占位符 {name}"""
    src = """
from mc.log import ilog

def test_named(name: str, value: int) -> None:
    # 命名参数 {name} - 使用键值对格式
    ilog("{name} {value}", name=name, value=value)
    ilog("Answer is {answer}", answer=42)
"""
    block = compile_chunk(src)
    assert_code_contains(
        block,
        """
        void test_named(const std::string& name, int value) {
            ilog("{name} {value}", ("name", name), ("value", value));
            ilog("Answer is {answer}", ("answer", 42));
        }
        """,
    )


def test_mixed_args_logging():
    """测试混合参数日志 - 位置参数和命名参数混合使用"""
    src = """
from mc.log import ilog

def test_mixed(user: str, age: int, balance: float) -> None:
    # 混合位置参数和命名参数
    ilog("{} is {age} years old", user, age=age)
    ilog("{} has {balance} dollars", "Bob", balance=balance)
"""
    block = compile_chunk(src)
    assert_code_contains(
        block,
        """
        void test_mixed(const std::string& user, int age, double balance) {
            ilog("{} is {age} years old", user, ("age", age));
            ilog("{} has {balance} dollars", "Bob", ("balance", balance));
        }
        """,
    )


def test_all_log_levels():
    """测试所有日志级别"""
    src = """
from mc.log import tlog, dlog, ilog, nlog, wlog, elog, flog

def test_levels(msg: str) -> None:
    tlog("Trace: {}", msg)
    dlog("Debug: {}", msg)
    ilog("Info: {}", msg)
    nlog("Notice: {}", msg)
    wlog("Warning: {}", msg)
    elog("Error: {}", msg)
    flog("Fatal: {}", msg)
"""
    block = compile_chunk(src)
    assert_code_contains(
        block,
        """
        void test_levels(const std::string& msg) {
            tlog("Trace: {}", msg);
            dlog("Debug: {}", msg);
            ilog("Info: {}", msg);
            nlog("Notice: {}", msg);
            wlog("Warning: {}", msg);
            elog("Error: {}", msg);
            flog("Fatal: {}", msg);
        }
        """,
    )


def test_format_specifications():
    """测试格式说明符 - {:.2f}, {:>10}, {:<10}, {:04d}"""
    src = """
from mc.log import ilog

def test_format_specs() -> None:
    # 自增索引带格式
    ilog("{:.2f} {}", 3.14159, "pi")
    
    # 显式索引带格式
    ilog("{0:.2f} {1:>10}", 3.14159, "right")
    
    # 命名参数带格式
    ilog("{name:<10} {value:04d}", name="Number", value=42)
    
    # 混合格式说明符
    ilog("{} {precision:.3f} {width:>8}", "Value:", precision=2.71828, width="aligned")
"""
    block = compile_chunk(src)
    assert_code_contains(
        block,
        """
        void test_format_specs() {
            ilog("{:.2f} {}", 3.14159, "pi");
            ilog("{0:.2f} {1:>10}", 3.14159, "right");
            ilog("{name:<10} {value:04d}", ("name", "Number"), ("value", 42));
            ilog("{} {precision:.3f} {width:>8}", "Value:", ("precision", 2.71828), ("width", "aligned"));
        }
        """,
    )


def test_dynamic_format_parameters():
    """测试动态格式参数 - 嵌套大括号格式"""
    src = """
from mc.log import ilog

def test_dynamic_format() -> None:
    # 使用命名参数作为动态宽度和精度
    ilog("{value:{width}.{precision}f}", value=3.14159, width=10, precision=3)
    
    # 混合索引和命名参数的动态格式
    ilog("{0:{width}.2f}", 3.14159, width=8)
    
    # 复杂嵌套格式
    ilog("{data:{w}.{p}f} {label:>{w}}", data=123.456, w=12, p=2, label="test")
"""
    block = compile_chunk(src)
    assert_code_contains(
        block,
        """
        void test_dynamic_format() {
            ilog("{value:{width}.{precision}f}", ("value", 3.14159), ("width", 10), ("precision", 3));
            ilog("{0:{width}.2f}", 3.14159, ("width", 8));
            ilog("{data:{w}.{p}f} {label:>{w}}", ("data", 123.456), ("w", 12), ("p", 2), ("label", "test"));
        }
        """,
    )


def test_complex_logging_scenarios():
    """测试复杂的日志场景"""
    src = """
from mc.log import ilog

def test_complex(x: int, y: int, name: str) -> None:
    # 单个命名参数
    ilog("{x}", x=x)
    
    # 多个位置参数
    ilog("{} {} {}", x, y, name)
    
    # 长命名参数
    ilog("{very_long_parameter_name}", very_long_parameter_name="value")
    
    # 混合复杂场景
    ilog("User {} has {} points and {status}", name, x, status="active")
"""
    block = compile_chunk(src)
    assert_code_contains(
        block,
        """
        void test_complex(int x, int y, const std::string& name) {
            ilog("{x}", ("x", x));
            ilog("{} {} {}", x, y, name);
            ilog("{very_long_parameter_name}", ("very_long_parameter_name", "value"));
            ilog("User {} has {} points and {status}", name, x, ("status", "active"));
        }
        """,
    )
